import base64
import binascii
import uuid

from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from rest_framework import serializers
from .models import Project
from ..CanvasElementManagement.models import TextElement, MaskElement, CanvasElement
from ..CanvasesManagement.models import Canvas
from ..CanvasesManagement.serializers import CanvasSerializer


class ListProjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = "__all__"
        read_only_fields = ['id', 'created_at', 'updated_at']


class Base64ImageField(serializers.CharField):
    """处理Base64图片并存储到文件系统，返回存储路径"""

    def to_internal_value(self, data):
        try:
            # 解析数据URI格式（data:image/png;base64,...）
            if ';base64,' in data:
                header, data = data.split(';base64,', 1)
                mime_type = header.split('/')[-1].split(';')[0].lower()
            else:
                mime_type = 'jpeg'  # 默认类型

            # 验证图片类型
            if mime_type not in ['jpeg', 'png']:
                raise serializers.ValidationError("仅支持JPEG/PNG格式")

            # 解码Base64数据
            decoded_file = base64.b64decode(data)

            # 验证文件大小（10MB）
            if len(decoded_file) > 10 * 1024 * 1024:
                raise serializers.ValidationError("文件大小超过10MB")

            # 生成存储路径
            file_name = f"{uuid.uuid4()}.{mime_type}"
            storage_path = f"images/{self.context['project'].name}/{file_name}"

            # 保存文件到存储系统
            default_storage.save(
                storage_path,
                ContentFile(decoded_file)
            )
            return storage_path

        except (TypeError, ValueError, binascii.Error) as e:
            raise serializers.ValidationError("无效的Base64图片数据")


class ProjectTextElementSerializer(serializers.ModelSerializer):
    class Meta:
        model = TextElement
        fields = [
            'text_content', 'font_family', 'font_size', 'font_weight',
            'font_style', 'text_align', 'line_height', 'letter_spacing',
            'text_color', 'text_effects', 'text_transform', 'writing_mode'
        ]
        extra_kwargs = {
            'text_content': {'required': False},
            'font_family': {'required': False},
            'font_size': {'required': False},
            'font_weight': {'required': False},
            'font_style': {'required': False},
            'text_align': {'required': False},
            'line_height': {'required': False},
            'letter_spacing': {'required': False},
            'text_color': {'required': False},
            'text_effects': {'required': False},
            'text_transform': {'required': False},
            'writing_mode': {'required': False}
        }


class ProjectMaskElementSerializer(serializers.ModelSerializer):
    class Meta:
        model = MaskElement
        fields = ['mask_type', 'mask_content', 'asset']
        extra_kwargs = {
            'mask_type': {'required': False},
            'mask_content': {'required': False},
            'asset': {'required': False}
        }


class ProjectCanvasElementSerializer(serializers.ModelSerializer):
    text_element = ProjectTextElementSerializer(required=False, allow_null=True)
    mask_element = ProjectMaskElementSerializer(required=False, allow_null=True)

    class Meta:
        model = CanvasElement
        fields = [
            'id', 'type', 'name', 'position', 'size', 'rotation', 'opacity',
            'visible', 'locked', 'z_index', 'text_element', 'mask_element'
        ]
        extra_kwargs = {
            'id': {'read_only': False},
            'type': {'required': False},
            'name': {'required': False},
            'position': {'required': False},
            'size': {'required': False},
            'rotation': {'required': False},
            'opacity': {'required': False},
            'visible': {'required': False},
            'locked': {'required': False},
            'z_index': {'read_only': True}
        }

    def validate(self, data):
        if data['type'] == 'text' and not data.get('text_element'):
            raise serializers.ValidationError("Text元素需要text_element字段")
        if data['type'] == 'mask' and not data.get('mask_element'):
            raise serializers.ValidationError("Mask元素需要mask_element字段")
        return data

    def create(self, validated_data):
        element_type = validated_data.pop('type')
        text_data = validated_data.pop('text_element', None)
        mask_data = validated_data.pop('mask_element', None)

        element = CanvasElement.objects.create(**validated_data)

        if element_type == 'text':
            TextElement.objects.create(element=element, **text_data)
        elif element_type == 'mask':
            MaskElement.objects.create(element=element, **mask_data)

        return element

    def update(self, instance, validated_data):
        # 更新 CanvasElement 基础字段
        instance.type = validated_data.get('type', instance.type)
        instance.name = validated_data.get('name', instance.name)
        instance.position = validated_data.get('position', instance.position)
        instance.size = validated_data.get('size', instance.size)
        instance.rotation = validated_data.get('rotation', instance.rotation)
        instance.opacity = validated_data.get('opacity', instance.opacity)
        instance.visible = validated_data.get('visible', instance.visible)
        instance.locked = validated_data.get('locked', instance.locked)
        instance.save()

        # 处理嵌套字段的更新
        text_data = validated_data.pop('text_element', None)
        mask_data = validated_data.pop('mask_element', None)

        if instance.type == 'text' and text_data:
            text_element = instance.text_element
            text_serializer = ProjectTextElementSerializer(text_element, data=text_data, partial=True)
            text_serializer.is_valid(raise_exception=True)
            text_serializer.save()

        elif instance.type == 'mask' and mask_data:
            mask_element = instance.mask_element
            mask_serializer = ProjectMaskElementSerializer(mask_element, data=mask_data, partial=True)
            mask_serializer.is_valid(raise_exception=True)
            mask_serializer.save()

        return instance


class ProjectCanvasSerializer(serializers.ModelSerializer):
    contentBlocks = ProjectCanvasElementSerializer(source='elements', many=True, required=False)

    class Meta:
        model = Canvas
        fields = [
            'id', 'name', 'position', 'canvas_size', 'background',
            'background_image', 'original_size', 'contentBlocks'
        ]
        extra_kwargs = {
            'id': {'read_only': False},
            'name': {'required': False},
            'canvas_size': {'required': False},
            'background': {'required': False},
            'original_size': {'required': False},
            'position': {'read_only': True},
            'background_image': {'required': False},
        }

    def create(self, validated_data):
        elements_data = validated_data.pop('elements', [])
        canvas = Canvas.objects.create(**validated_data)

        for element_data in elements_data:
            element_serializer = ProjectCanvasElementSerializer(data=element_data)
            element_serializer.is_valid(raise_exception=True)
            element_serializer.save(canvas=canvas)

        return canvas

    def update(self, instance, validated_data):
        elements_data = validated_data.pop('elements', [])

        # 更新画布基础字段
        instance.name = validated_data.get('name', instance.name)
        instance.canvas_size = validated_data.get('canvas_size', instance.canvas_size)
        instance.background = validated_data.get('background', instance.background)
        instance.background_image = validated_data.get('background_image', instance.background_image)
        instance.save()

        # 管理现有元素（更新/删除）
        existing_elements = {str(e.id): e for e in instance.elements.all()}
        received_ids = set()

        for element_data in elements_data:
            element_id = element_data.get('id')
            if element_id and element_id in existing_elements:
                # 更新现有元素
                element = existing_elements[element_id]
                element_serializer = ProjectCanvasElementSerializer(element, data=element_data, partial=True)
                element_serializer.is_valid(raise_exception=True)
                element_serializer.save(canvas=instance)
                received_ids.add(element_id)
            else:
                # 创建新元素
                element_serializer = ProjectCanvasElementSerializer(data=element_data)
                element_serializer.is_valid(raise_exception=True)
                element_serializer.save(canvas=instance)

        return instance


class UpdateProjectSerializer(serializers.ModelSerializer):
    thumbnail_base64 = Base64ImageField(
        required=False,
        write_only=True,
        help_text="Base64编码的缩略图（支持JPEG/PNG，最大10MB）"
    )
    canvases = ProjectCanvasSerializer(many=True, required=False)

    class Meta:
        model = Project
        fields = [
            'id', 'name', 'description', 'thumbnail_url',
            'settings', 'last_modified', 'created_at',
            'updated_at', 'auto_save', 'auto_save_interval',
            'thumbnail_base64', 'canvases'
        ]
        extra_kwargs = {
            'name': {'required': False},
            'description': {'required': False},
            'settings': {'required': False},
            'last_modified': {'required': False},
            'auto_save': {'required': False},
            'auto_save_interval': {'required': False},
        }
        read_only_fields = ['id', 'created_at', 'updated_at', 'thumbnail_url']

    def validate(self, attrs):
        # 将project实例传递给字段上下文
        attrs['project'] = self.instance
        return attrs

    def update(self, instance, validated_data):
        # 处理缩略图更新
        new_thumbnail_path = validated_data.pop('thumbnail_base64', None)
        canvases_data = validated_data.pop('canvases', [])

        if new_thumbnail_path:
            # 删除旧文件（保留默认缩略图）
            if instance.thumbnail_url and instance.thumbnail_url != 'images/default.png':
                default_storage.delete(instance.thumbnail_url)

            # 更新存储路径
            instance.thumbnail_url = new_thumbnail_path

        # 更新项目基础字段
        project = super().update(instance, validated_data)

        # 处理画布更新
        existing_canvases = {str(c.id): c for c in project.canvases.all()}

        # 处理新建/更新画布
        for canvas_data in canvases_data:
            canvas_id = canvas_data.get('id')
            if canvas_id in existing_canvases:
                # 更新现有画布
                canvas = existing_canvases[canvas_id]
                canvas_serializer = ProjectCanvasSerializer(
                    canvas,
                    data=canvas_data,
                    context={'project': project}
                )
                canvas_serializer.is_valid(raise_exception=True)
                canvas_serializer.save(project=project)
            else:
                # 创建新画布
                canvas_serializer = ProjectCanvasSerializer(
                    data=canvas_data,
                    context={'project': project}
                )
                canvas_serializer.is_valid(raise_exception=True)
                canvas_serializer.save(project=project)

        return project


class ProjectSerializer(serializers.ModelSerializer):
    canvases = CanvasSerializer(many=True, read_only=True)  # 只读，用于响应

    class Meta:
        model = Project
        fields = [
            'id', 'name', 'description', 'settings', 'last_modified',
            'auto_save', 'auto_save_interval', 'created_at', 'updated_at',
            'thumbnail_url', 'canvases'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'thumbnail_url', 'last_modified']


class CreateProjectSerializer(serializers.ModelSerializer):
    canvases = CanvasSerializer(many=True, required=False)  # 允许不提供，自动创建默认画布

    class Meta:
        model = Project
        fields = [
            'id', 'name', 'description', 'settings', 'created_at',
            'updated_at', 'auto_save', 'auto_save_interval', 'canvases'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'thumbnail_url', 'last_modified']

    def create(self, validated_data):
        # 提取画布数据（如果存在）
        canvases_data = validated_data.pop('canvases', [])
        # 创建项目实例
        project = Project.objects.create(**validated_data)
        # 创建客户端提供的画布
        for canvas_data in canvases_data:
            Canvas.objects.create(project=project, **canvas_data)
        # 如果没有提供画布，创建默认初始画布
        if not canvases_data or len(canvases_data) == 0:
            Canvas.objects.create(
                project=project,
                name="初始画布",
                canvas_size={'width': 1920, 'height': 1080},
                background={'type': 'color', 'value': '#ffffff', 'position': {'x': 0, 'y': 0}},
                original_size={'width': 1920, 'height': 1080}
            )
        return project


class DetailProjectTextElementSerializer(serializers.ModelSerializer):
    class Meta:
        model = TextElement
        fields = "__all__"


class DetailProjectMaskElementSerializer(serializers.ModelSerializer):
    class Meta:
        model = MaskElement
        fields = "__all__"


class DetailProjectCanvasElementSerializer(serializers.ModelSerializer):
    text_element = DetailProjectTextElementSerializer(required=False)
    mask_element = DetailProjectMaskElementSerializer(required=False)

    class Meta:
        model = CanvasElement
        fields = "__all__"


class DetailProjectCanvasSerializer(serializers.ModelSerializer):
    contentBlocks = DetailProjectCanvasElementSerializer(source='elements', many=True, required=False)

    class Meta:
        model = Canvas
        fields = [
            'id', 'name', 'position', 'canvas_size', 'background',
            'background_image', 'original_size', 'created_at', 'updated_at', 'contentBlocks'
        ]


class DetailProjectSerializer(serializers.ModelSerializer):
    canvases = DetailProjectCanvasSerializer(many=True, read_only=True)  # 只读，用于响应

    class Meta:
        model = Project
        fields = [
            'id', 'name', 'description', 'thumbnail_url', 'settings', 'last_modified',
            'auto_save', 'auto_save_interval', 'created_at', 'updated_at', 'canvases'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'thumbnail_url', 'last_modified']
